package com.price.httplib.websocket

import android.os.Handler
import android.os.Looper
import android.os.Message
import com.price.common.extend.doCustomCrashListener
import com.price.common.extend.logDebug
import com.price.common.extend.logWarn
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okio.ByteString


class WebSocketManager constructor(builder: WebSocketBuilder) : WebSocketListener() {

    init {
        builder.also {
            this.mSocketURL = it.url
            this.mHeart = it.heart
            this.mHeartTime = it.heartTime
            this.sClient = it.okHttpClient
            this.mReConnect = it.reConnect
            this.mReConnectTime = it.reConnectTime
            this.myWebSocketListener = it.listener
            this.mHeaderParams=it.headerParams
        }
    }


    private var sClient: OkHttpClient? = null
    private var sWebSocket: WebSocket? = null
    private var mSocketURL: String? = null
    private var mHeart: String? = null
    private var mHeartTime: Long? = 5000
    private var mReConnect: Boolean? = false
    private var mReConnectTime: Long? = 5000
    private var mHeaderParams:Map<String,String>?=null

    private var isConnect: Boolean = false

    private var myWebSocketListener: MyWebSocketListener? = null

    private val NORMAL_CLOSURE_STATUS = 1000
    private val ACTION_EMPTYMSG = 1400
    private val ACTION_FAILURE = 1401


    private val handler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)

            when (msg.what) {
                ACTION_EMPTYMSG -> {
                    if (mHeart != null) {
                        sendData(mHeart!!)
                        // 每隔5秒发送一次心跳包，检测连接没有断开
                        this.sendEmptyMessageDelayed(ACTION_EMPTYMSG, mHeartTime!!)
                    }
                }

                ACTION_FAILURE -> {
                    if (mReConnect!!) {
                        connect()
                        this.sendEmptyMessageDelayed(ACTION_FAILURE, mReConnectTime!!)
                    }
                }

                else -> {}
            }
        }
    }

    fun connect() {
        if (isConnect) {
            logWarn("websocket is connecting")
            return
        }
        if (!mSocketURL.isNullOrEmpty()) {
            isConnect = true

            myWebSocketListener?.onStatus(mSocketURL!!, 4)

            logDebug("Socket连接！！！------$mSocketURL")
            val builder: Request.Builder = Request.Builder().url(mSocketURL!!)

            if(mHeaderParams!=null) {
                for (header in mHeaderParams!!) {
                    builder.addHeader(header.key,header.value)
                }
            }

            val request = builder.build()

            sWebSocket = sClient?.newWebSocket(request, this)

        }
    }

    fun sendData(info: String): Boolean {
        if (sWebSocket != null) {
            logDebug("sendData: $mSocketURL，数据：$info")
            if (info.isNotEmpty()) {
                return sWebSocket!!.send(info)
            }
        }
        return false
    }

    override fun onMessage(webSocket: WebSocket, text: String) {
        if (text.isNotEmpty()) {
            onGetMsg(text)
        }
    }

    override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
        if (bytes.hex().isNotEmpty()) {
            onGetMsg(bytes.hex())
        }
    }


    override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
        logDebug("onClosing() called with: code = [$code], reason = [$reason]")
        isConnect = false
        myWebSocketListener?.onStatus(mSocketURL!!, 3)
    }

    override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
        isConnect = false
        myWebSocketListener?.onStatus(mSocketURL!!, 2)

        logDebug("onClosed() called with: code = [$code], reason = [$reason]")
    }

    override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
        super.onFailure(webSocket, t, response)
        logDebug("Socket连接失败！！！----------------$mSocketURL-------------连接失败！！！")

        isConnect = false

        doCustomCrashListener?.onCrash(t)

        myWebSocketListener?.onStatus(mSocketURL!!, 0)
        close()
        handler.sendEmptyMessage(ACTION_FAILURE)
    }


    override fun onOpen(webSocket: WebSocket, response: Response) {
        super.onOpen(webSocket, response)
        logDebug("Socket连接成功！！！----------------$mSocketURL-------------连接成功！！！")
        logDebug("response:${response.code}")
        isConnect = true
        handler.removeMessages(ACTION_FAILURE)
        handler.sendEmptyMessage(ACTION_EMPTYMSG)

        myWebSocketListener?.onStatus(mSocketURL!!, 1)

    }

    fun close() {
        handler.removeMessages(ACTION_EMPTYMSG)
        handler.removeCallbacksAndMessages(null)

        sWebSocket?.close(NORMAL_CLOSURE_STATUS, "Goodbye!")
        sWebSocket = null

        myWebSocketListener?.onStatus(mSocketURL!!, 3)
//        instance = null

    }

    private fun onGetMsg(msg: String) {
        logDebug("接收Socket消息：$msg")
        myWebSocketListener?.onMessage(mSocketURL!!, msg)
    }


//    companion object {
//        @Volatile
//        private var instance: WebSocketManager? = null
//        fun getInstance(builder: WebSocketBuilder): WebSocketManager {
//            if (instance == null) {
//                synchronized(WebSocketManager::class.java) {
//                    if (instance == null) {
//                        instance = WebSocketManager(builder)
//                    }
//                }
//            }
//            return instance!!
//        }
//    }
}